using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Xml.Serialization;
using MaxAlarm.Core.Cryptography;

namespace MaxAlarm.Core.Settings
{
    [XmlType("account")]
    public class AccountSettingItem : DependencyObject
    {
        public static readonly DependencyProperty LoginProperty =
            DependencyProperty.Register("Login", typeof (string), typeof (AccountSettingItem), new PropertyMetadata(default(string)));

        [XmlAttribute("login")]
        public string Login
        {
            get { return (string) GetValue(LoginProperty); }
            set { SetValue(LoginProperty, value); }
        }


        [XmlIgnore]
        private string _cryptedPass;

        [XmlIgnore]
        public string Password
        {
            get { return CryptorProviderHelper.Decrypt(_cryptedPass); }
            set { _cryptedPass = CryptorProviderHelper.Encrypt(value); }
        }

        [XmlAttribute("password")]
        public string CryptedPassword
        {
            get { return _cryptedPass; }
            set { _cryptedPass = value; }
        }

    }

    [XmlType("accounts-settings")]
    public class AccountsSettings : DependencyObject, ICloneable
    {
        public static readonly DependencyProperty AccountsProperty =
            DependencyProperty.Register("Accounts", typeof (ObservableCollection<AccountSettingItem>), typeof (AccountsSettings), new PropertyMetadata(null));

        [XmlElement("account")]
        public ObservableCollection<AccountSettingItem> Accounts
        {
            get { return (ObservableCollection<AccountSettingItem>) GetValue(AccountsProperty); }
            set { SetValue(AccountsProperty, value); }
        }

        public AccountsSettings()
        {
            Accounts = new ObservableCollection<AccountSettingItem>();
        }

        public string this[string login]
        {
            get 
            { 
                var item = Accounts.Single(e => e.Login == login);
                return item == null ? null : item.Password;
            }
            set 
            {
                var index = FindIndex(Accounts, login);

                if (index >= 0)
                {
                    var element = Accounts[index];
                    element.Password = value;
                    SetToTop(login);
                }
                else
                {
                    Accounts.Insert(0, new AccountSettingItem {Login = login, Password = value});
                }
            }
        }

        public void SetToTop(string login)
        {
            var index = FindIndex(Accounts, login);

            if (index == -1)
                return;

            var element = Accounts[index];
            Accounts.RemoveAt(index);
            Accounts.Insert(0, element);
        }

        public bool Contains(string login)
        {
            return Accounts.Any(e => e.Login == login);
        }

        public object Clone()
        {
            return new AccountsSettings
                       {
                           Accounts = new ObservableCollection<AccountSettingItem>(Accounts.Select(e=>e))
                       };
        }

        private static int FindIndex(ObservableCollection<AccountSettingItem> collection, string login)
        {
            for (var i = 0; i < collection.Count; i++)
                if (collection[i].Login == login)
                    return i;

            return -1;
        }
    }
}
